import * as Cesium from 'cesium'

export class CesiumManager {
  public viewer: Cesium.Viewer | null = null
  public onCoordinatesUpdate?: (longitude: number, latitude: number) => void
  public onEntitySelected?: (entity: Cesium.Entity | null) => void
  private selectedEntity: Cesium.Entity | null = null

  constructor(private containerId: string) {}

  async init(): Promise<void> {
    try {
      // 设置Cesium的默认访问令牌
      Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJjNjlhOWFmMC1mNmZhLTQ2YWYtYTQwZi1lZDcxYmU1MjU4NzEiLCJpZCI6MTM0NjkyLCJpYXQiOjE3NTQ2MTYzNjV9.Q301li6WNAT87LIlwnDF_LllRkIJnnrk4FYvKd86G30'

      // 创建Cesium Viewer，使用最基本的配置
      this.viewer = new Cesium.Viewer(this.containerId, {
        // 界面配置
        homeButton: true,
        sceneModePicker: true,
        baseLayerPicker: true,
        navigationHelpButton: true,
        animation: false,
        timeline: false,
        fullscreenButton: true,
        vrButton: false,
        geocoder: true,
        
        // 场景配置
        scene3DOnly: false,
        requestRenderMode: false,
        maximumRenderTimeChange: Infinity
      })

      // 修复Canvas尺寸问题
      this.fixCanvasSize()

      // 配置场景参数
      this.configureScene()

      // 添加事件监听
      this.addEventListeners()

      console.log('Cesium场景初始化完成')
    } catch (error) {
      console.error('Cesium初始化失败:', error)
      throw error
    }
  }

  private fixCanvasSize(): void {
    if (!this.viewer) return

    const container = document.getElementById(this.containerId)
    if (!container) return

    // 确保容器有正确的尺寸
    const rect = container.getBoundingClientRect()
    if (rect.width === 0 || rect.height === 0) {
      console.warn('容器尺寸为0，尝试修复...')
      container.style.width = '100%'
      container.style.height = '100%'
      container.style.minHeight = '100vh'
    }

    // 修复Canvas尺寸
    const canvas = this.viewer.canvas
    if (canvas) {
      canvas.setAttribute('width', container.clientWidth.toString())
      canvas.setAttribute('height', container.clientHeight.toString())
      canvas.style.width = '100%'
      canvas.style.height = '100%'
      canvas.style.display = 'block'
      
      // 强制Cesium重新计算尺寸
      this.viewer.forceResize()
      
      console.log(`Canvas尺寸已修复: ${container.clientWidth}×${container.clientHeight}`)
    }
  }

  private configureScene(): void {
    if (!this.viewer) return

    const scene = this.viewer.scene
    
    // 启用光照
    scene.globe.enableLighting = true
    
    // 配置大气效果（安全检查）
    if (scene.skyAtmosphere) {
      scene.skyAtmosphere.show = true
    }
    
    // 配置深度测试
    scene.globe.depthTestAgainstTerrain = true
    
    // 配置相机参数
    this.viewer.camera.percentageChanged = 0.1
    
    // 设置默认视角（中国北京）
    this.viewer.camera.setView({
      destination: Cesium.Cartesian3.fromDegrees(116.397, 39.909, 1000),
      orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-45),
        roll: 0.0
      }
    })
  }

  private addEventListeners(): void {
    if (!this.viewer) return

    // 监听窗口大小变化
    window.addEventListener('resize', () => {
      if (this.viewer) {
        this.fixCanvasSize()
        this.viewer.resize()
      }
    })

    // 监听鼠标移动事件，更新坐标显示
    this.viewer.canvas.addEventListener('mousemove', (event: MouseEvent) => {
      const pickedPosition = this.viewer!.camera.pickEllipsoid(
        new Cesium.Cartesian2(event.clientX, event.clientY),
        this.viewer!.scene.globe.ellipsoid
      )
      
      if (pickedPosition && this.onCoordinatesUpdate) {
        const cartographic = Cesium.Cartographic.fromCartesian(pickedPosition)
        const longitude = parseFloat(Cesium.Math.toDegrees(cartographic.longitude).toFixed(6))
        const latitude = parseFloat(Cesium.Math.toDegrees(cartographic.latitude).toFixed(6))
        
        this.onCoordinatesUpdate(longitude, latitude)
      }
    })

    // 监听左键点击事件
    this.viewer.cesiumWidget.canvas.addEventListener('click', (event: MouseEvent) => {
      const pickedObject = this.viewer!.scene.pick(new Cesium.Cartesian2(event.clientX, event.clientY))
      if (Cesium.defined(pickedObject)) {
        console.log('点击了对象:', pickedObject)
        // 处理实体选择
        if (pickedObject.id && pickedObject.id instanceof Cesium.Entity) {
          this.selectEntity(pickedObject.id)
        }
      } else {
        // 点击空白区域，取消选择
        this.deselectEntity()
      }
    })
  }

  flyToEntity(entity: Cesium.Entity): void {
    if (entity && this.viewer) {
      this.viewer.flyTo(entity, {
        duration: 2.0,
        offset: new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-45), 500)
      })
    }
  }

  flyTo(longitude: number, latitude: number, height: number): void {
    if (!this.viewer) return

    this.viewer.camera.flyTo({
      destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height),
      duration: 2.0
    })
  }

  forceCanvasResize(): void {
    this.fixCanvasSize()
  }

  selectEntity(entity: Cesium.Entity): void {
    // 取消之前的选择
    this.deselectEntity()
    
    this.selectedEntity = entity
    
    // 根据实体类型设置高亮
    if (entity.box) {
      entity.box.material = new Cesium.ColorMaterialProperty(Cesium.Color.RED.withAlpha(0.8))
      entity.box.outlineColor = new Cesium.ConstantProperty(Cesium.Color.YELLOW)
    } else if (entity.model) {
      entity.model.color = new Cesium.ConstantProperty(Cesium.Color.RED.withAlpha(0.8))
      entity.model.colorBlendMode = new Cesium.ConstantProperty(Cesium.ColorBlendMode.MIX)
      entity.model.colorBlendAmount = new Cesium.ConstantProperty(0.7)
    }
    
    // 通知选择事件
    if (this.onEntitySelected) {
      this.onEntitySelected(entity)
    }
    
    console.log('已选中实体:', entity.name || '未命名')
  }

  deselectEntity(): void {
    if (!this.selectedEntity) return
    
    const entity = this.selectedEntity
    
    // 恢复原始样式
    if (entity.box) {
      entity.box.material = new Cesium.ColorMaterialProperty(Cesium.Color.CYAN.withAlpha(0.7))
      entity.box.outlineColor = new Cesium.ConstantProperty(Cesium.Color.BLUE)
    } else if (entity.model) {
      entity.model.color = new Cesium.ConstantProperty(Cesium.Color.WHITE)
      entity.model.colorBlendMode = new Cesium.ConstantProperty(Cesium.ColorBlendMode.HIGHLIGHT)
      entity.model.colorBlendAmount = new Cesium.ConstantProperty(0.0)
    }
    
    // 通知取消选择事件
    if (this.onEntitySelected) {
      this.onEntitySelected(null)
    }
    
    console.log('已取消选中实体:', entity.name || '未命名')
    this.selectedEntity = null
  }

  getSelectedEntity(): Cesium.Entity | null {
    return this.selectedEntity
  }

  resetView(): void {
    if (!this.viewer) return

    this.viewer.camera.setView({
      destination: Cesium.Cartesian3.fromDegrees(116.397, 39.909, 1000),
      orientation: {
        heading: Cesium.Math.toRadians(0),
        pitch: Cesium.Math.toRadians(-45),
        roll: 0.0
      }
    })
  }

  destroy(): void {
    if (this.viewer) {
      this.viewer.destroy()
      this.viewer = null
    }
  }
}
